﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PBDesk.Utilities;

namespace PBDesk.Utilities
{
    public class MyUtils
    {
        private static Random RndGenerator = new Random();

        #region Enum Methods

        public static T ParseEnum<T>(string inString, bool ignoreCase = true, bool throwException = true) where T : struct
        {
            return (T)ParseEnum<T>(inString, default(T), ignoreCase, throwException);
        }
        
        public static T ParseEnum<T>(string inString, T defaultValue, 
                               bool ignoreCase = true, bool throwException = false) where T : struct
        {
            T returnEnum = defaultValue;

            if (!typeof(T).IsEnum || inString.IsNullOrEmpty())   
            {
                throw new InvalidOperationException("Invalid Enum Type or Input String 'inStr'. " + typeof(T).ToString() + "  must be an Enum");   
            }

            try
            {
                bool success = Enum.TryParse<T>(inString, ignoreCase, out returnEnum);
                if (!success && throwException)
                {
                    throw new InvalidOperationException("Invalid Cast");
                }
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("Invalid Cast", ex);
            }           
 
            return returnEnum;
        }

        public static T ParseEnum<T>(int input, bool throwException = true) where T : struct
        {
            return (T)ParseEnum<T>(input, default(T),  throwException);
        }
        public static T ParseEnum<T>(int input, T defaultValue, bool throwException = false) where T : struct
        {
            T returnEnum = defaultValue;
            if (!typeof(T).IsEnum)
            {
                throw new InvalidOperationException("Invalid Enum Type. " + typeof(T).ToString() + "  must be an Enum");   
            }
            if (Enum.IsDefined(typeof(T), input))
            {
                returnEnum = (T)Enum.ToObject(typeof(T), input);
            }
            else
            {
                if (throwException)
                {
                    throw new InvalidOperationException("Invalid Cast");
                }
            }
            
            return returnEnum;

        }
        #endregion

        #region Array/Shuffle Methods

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="arr"></param>
        /// <returns></returns>
        public static T[] ShuffleArray<T>(T[] arr)
        {
            List<KeyValuePair<int, T>> list = new List<KeyValuePair<int, T>>();
            foreach (T item in arr)
            {
                list.Add(new KeyValuePair<int, T>(RndGenerator.Next(), item));
            }
            var sorted = from listItem in list orderby listItem.Key select listItem;

            T[] result = new T[arr.Length];
            int i =0;
            foreach (KeyValuePair<int, T> pair in sorted)
            {
                result[i] = pair.Value;
                i++;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="size"></param>
        /// <param name="startValue"></param>
        /// <returns></returns>
        public static int[] GetShuffleArr(int size, int startValue = 0)
        {
            
            if (size > 0)
            {
                
                    int[] arr = new int[size];
                    for (int i = 0, j = startValue; i < size; i++, j++)
                    {
                        arr[i] = j;
                    }
                    return ShuffleArray<int>(arr);

            }
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="size"></param>
        /// <param name="startValue"></param>
        /// <returns></returns>
        public static string GetShuffleCSV(int size, int startValue = 0)
        {
            int[] arr = GetShuffleArr(size, startValue);
            if (arr != null && arr.Length > 0)
                return String.Join(",", arr);
            else
                return string.Empty;           
        }

        #endregion


    }
}
